﻿/*
 * util.h
 *
 * Created: 10.3.2011 г. 16:08:48
 *  Author: mmirev
 */
#ifndef UTIL_H_
#define UTIL_H_

#include <inttypes.h>

//#define NUMBEROFELEMENTS(x) (sizeof(x)/sizeof((x)[0]))
#define NUMBEROFELEMENTS(x) (sizeof(x)/sizeof(*(x)))

//#define NULL  null

#define TRUE		(1)
#define FALSE		(0)

//DDR
#define IN	(0)
#define OUT	(1)
//PORT,PIN
#define ON	(1)
#define OFF	(0)
//PORT
#define PULLUP_ENABLED (1)
#define PULLUP_DISABLED (0)

#define DDR(port) (*(&port - 1))
#define PIN(port) (*(&port - 2))

#define SET_AS_OUTPUT(PIN_NAME) PIN_NAME##_output()
#define SET_AS_INPUT(PIN_NAME) PIN_NAME##_input()
#define OUTPUT_HI(PIN_NAME) PIN_NAME##_hi()
#define OUTPUT_LO(PIN_NAME) PIN_NAME##_lo()
#define PIN_ALIAS(PIN_NAME,PORT,PIN_IDX) \
inline void PIN_NAME##_output(void) \
{\
  DDR(PORT) |= _BV(PIN_IDX); \
}\
inline void PIN_NAME##_input(void) \
{\
  DDR(PORT) &= ~_BV(PIN_IDX); \
}\
inline void PIN_NAME##_lo(void) \
{\
  PORT &= ~_BV(PIN_IDX); \
}\
inline void PIN_NAME##_hi(void) \
{\
  PORT |= _BV(PIN_IDX); \
}


typedef struct {
  uint8_t pin0:1;
  uint8_t pin1:1;
  uint8_t pin2:1;
  uint8_t pin3:1;
  uint8_t pin4:1;
  uint8_t pin5:1;
  uint8_t pin6:1;
  uint8_t pin7:1;
} pin_t;

typedef struct {
  uint8_t dd0:1;
  uint8_t dd1:1;
  uint8_t dd2:1;
  uint8_t dd3:1;
  uint8_t dd4:1;
  uint8_t dd5:1;
  uint8_t dd6:1;
  uint8_t dd7:1;
} ddr_t;

typedef struct {
  uint8_t port0:1;
  uint8_t port1:1;
  uint8_t port2:1;
  uint8_t port3:1;
  uint8_t port4:1;
  uint8_t port5:1;
  uint8_t port6:1;
  uint8_t port7:1;
} port_t;

typedef struct {
  uint8_t bit0:1;
  uint8_t bit1:1;
  uint8_t bit2:1;
  uint8_t bit3:1;
  uint8_t bit4:1;
  uint8_t bit5:1;
  uint8_t bit6:1;
  uint8_t bit7:1;
} register_t;

#ifdef PORTB
#define portb (*((volatile port_t*)&PORTB))
#define pinb (*((volatile pin_t*)&PINB))
#define ddrb (*((volatile ddr_t*)&DDRB))
#endif

#ifdef PORTC
#define portc (*((volatile port_t*)&PORTC))
#define pinc (*((volatile pin_t*)&PINC))
#define ddrc (*((volatile ddr_t*)&DDRC))
#endif

#ifdef PORTD
#define portd (*((volatile port_t*)&PORTD))
#define pind (*((volatile pin_t*)&PIND))
#define ddrd (*((volatile ddr_t*)&DDRD))
#endif

enum _PRESCALER {
  PRESCALE_STOP = 0,
  PRESCALE_0,
  PRESCALE_8,
  PRESCALE_64,
  PRESCALE_256,
  PRESCALE_1024
};

enum _E_PRESCALER {
  E_PRESCALE_STOP = 0,
  E_PRESCALE_0,
  E_PRESCALE_8,
  E_PRESCALE_32,
  E_PRESCALE_64,
  E_PRESCALE_128,
  E_PRESCALE_256,
  E_PRESCALE_1024
};

#endif /* UTIL_H_ */